﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace FIS.iDET.TemplateCreator
{
    public class ImageService
    {
        string imageFileName;
        
        Bitmap tifImage;        
        
        int totalFrames, currentFrame;
        
        Boolean fileLoadedOK = true;

        public ImageService()
        {
            fileLoadedOK = false;
        }

        public ImageService(string imageFileName)
        {
            this.imageFileName = imageFileName;
            LoadTifFile();
        }

        public string FileName
        {
            get
            {
                return imageFileName;
            }
            set
            {
                imageFileName = value;
                LoadTifFile();
            }
        }

        public int TotalFrames
        {
            get
            {
                return totalFrames;
            }
            set
            {
                totalFrames = value;
            }
        }

        public int Width
        {
            get
            {
                return tifImage.Width;
            }
        }

        public int Height
        {
            get
            {
                return tifImage.Height;
            }
        }

        public int CurrentFrame
        {
            get
            {
                return currentFrame;
            }
            set
            {
                currentFrame = value;
            }
        }

        public Boolean FileLoadedOK
        {
            get
            {
                return fileLoadedOK;
            }
        }

        private void LoadTifFile()
        {
            try
            {
                // decode tif image into bitmap
                tifImage = new Bitmap(imageFileName);

                // get total number of pages
                totalFrames = tifImage.GetFrameCount(FrameDimension.Page);
            }
            catch
            {
                fileLoadedOK = false;
                MessageBox.Show("Cannot load image file, please check if it is a valid TIFF image.", "Invalid image", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private double zoomFactor = 1;

        public Bitmap GetImageZoom(double zoomFactor, DoubleRectangle rect)
        {
            return GetImageZoom(zoomFactor, rect, false);
        }

        public Bitmap GetImageZoom(double zoomFactor, DoubleRectangle rect, bool mode) // mode = 1 , draw multiple Rect
        {
            // calculate Zoom size
            this.zoomFactor = zoomFactor;
            int zoomWidth = scaleUp(Width);
            int zoomHeight = scaleUp(Height);
            
            // create a new empty temporary bitmap
            Bitmap tmp = new Bitmap(zoomWidth, zoomHeight);
            tmp.SetResolution(tifImage.HorizontalResolution, tifImage.VerticalResolution);

            // create new graphic object
            Graphics g = Graphics.FromImage(tmp);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

            // Zoom here
            Rectangle srcRect = new Rectangle(0, 0, (int) Width, (int) Height);
            Rectangle desRect = new Rectangle(0, 0, (int) zoomWidth, (int) zoomHeight);
            g.DrawImage(tifImage, desRect, srcRect, GraphicsUnit.Pixel);
            
            // draw rulers
            float penStrokeWidth = (float)zoomFactor * 4;
            Pen penRed = new Pen(Color.Orange, penStrokeWidth);
            penRed.Alignment = System.Drawing.Drawing2D.PenAlignment.Outset;

            var intRect = new Rectangle();
            if (!mode)
            {
                intRect.X = scaleUp(rect.X);
                intRect.Y = scaleUp(rect.Y);
                intRect.Width = scaleUp(rect.Width);
                intRect.Height = scaleUp(rect.Height);
                if (rect.Width != 0 && rect.Height != 0)
                {
                    g.DrawRectangle(penRed, intRect);
                }
            }
            else
            {
                for (int i = 1; i <= FormTemplateCreator.rows; i++)
                {
                    if (rect.Width != 0 && rect.Height != 0)
                    {
                        intRect.Width = scaleUp(rect.Width);
                        intRect.Height = scaleUp(rect.Height);
                        intRect.X = scaleUp(rect.X);
                        intRect.Y = scaleUp(rect.Y + rect.Height * (i - 1));
                        g.DrawRectangle(penRed, intRect);
                    }
                }
            }
            // release Resource
            g.Dispose();
            GC.Collect();
            return tmp;
        }

        public Bitmap GetImageZoom(double zoomFactor)
        {
            // calculate Zoom size
            this.zoomFactor = zoomFactor;
            int zoomWidth = scaleUp(Width);
            int zoomHeight = scaleUp(Height);

            // create a new empty temporary bitmap
            Bitmap tmp = new Bitmap(zoomWidth, zoomHeight);
            tmp.SetResolution(tifImage.HorizontalResolution, tifImage.VerticalResolution);

            // create new graphic object
            Graphics g = Graphics.FromImage(tmp);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

            // Zoom here
            Rectangle srcRect = new Rectangle(0, 0, Width, Height);
            Rectangle desRect = new Rectangle(0, 0, zoomWidth, zoomHeight);
            g.DrawImage(tifImage, desRect, srcRect, GraphicsUnit.Pixel);

            // release Resource
            g.Dispose();
            GC.Collect();
            return tmp;
        }

        private int scaleUp(double original)
        {
            return (int) Math.Round(original * zoomFactor);
        }

        
        public void SetImageFrame(int frameToDisplay)
        {
            if (frameToDisplay >= 0 && frameToDisplay < totalFrames)
                currentFrame = frameToDisplay;
            
            // set active frame
            tifImage.SelectActiveFrame(FrameDimension.Page, currentFrame);
        }
        
        public Bitmap GetImageFrame(int frameToDisplay, double zoomFactor, DoubleRectangle rect)
        {
            SetImageFrame(frameToDisplay);

            return GetImageZoom(zoomFactor, rect,true);
        }
    }
}
